import 'package:e_reception_flutter/ui/app_main.dart';
import 'package:e_reception_flutter/utils/router_utils.dart';
import 'package:e_reception_flutter/utils/screen_utils.dart';
import 'package:e_reception_flutter/utils/vg_dialog_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

///通用带箭头上下的弹窗
class CommonWithUpOrDownArrowsDialog extends StatelessWidget {
  ///为避免箭头和主体衔接问题 重叠距离
  static const double sAvoidBorderTrimming = 0.5;

  ///屏幕高度
  final double _screenHeight;

  ///顶部状态栏高度
  final double _screenStatusBarHeight;

  ///底部状态栏高度
  final double _screenBottomBarHeight;

  final BuildContext parentContext;

  ///弹窗最大高度
  final double dialogMaxHeight;

  ///箭头尺寸
  final Size arrowsSize;

  ///弹窗距离盒子距离
  final double dialogToBoxOffsetY;

  ///箭头偏移量
  final double arrowsOffsetX;

  ///安全区域
  final double safeY;

  final Color arrowsColor;

  final Widget child;

  final Widget customArrowsWidget;

  CommonWithUpOrDownArrowsDialog._({
    Key key,
    @required this.child,
    @required this.parentContext,
    @required this.dialogMaxHeight,
    @required this.arrowsSize,
    this.dialogToBoxOffsetY = 0,
    this.arrowsOffsetX = 0,
    this.safeY = 0,
    this.arrowsColor = Colors.white,
    this.customArrowsWidget,
  })  : assert(parentContext != null, "parentContext is not current params"),
        assert(dialogMaxHeight != null && dialogMaxHeight > 0,
            "dialogMaxHeight 弹窗最大高度不正确"),
        assert(arrowsSize != null, "arrowsSize 箭头大小不能为空"),
        assert(child != null, "child 不能为空"),
        this._screenHeight = ScreenUtils.screenH(AppMain.context),
        this._screenBottomBarHeight =
            ScreenUtils.getBottomBarH(AppMain.context),
        this._screenStatusBarHeight =
            ScreenUtils.getStatusBarH(AppMain.context),
        super(key: key);

  static Future<T> navigatorPushForDialog<T>(
    BuildContext context, {
    @required double dialogMaxHeight,
    @required Size arrowsSize,
    @required Widget child,
    double dialogToBoxOffsetY = 0.0,
    double arrowsOffsetX = 0.0,
    double safeY = 0.0,
    Color arrowsColor,
    Color barrierColor,
  }) {
    assert(context != null,"parentContext不能为空");
    assert(child != null,"child不能为空");
    return VgDialogUtils.showCommonDialog<T>(
        context: context,
        barrierColor: barrierColor,
        child: CommonWithUpOrDownArrowsDialog._(
          parentContext: context,
          dialogMaxHeight: dialogMaxHeight,
          dialogToBoxOffsetY: dialogToBoxOffsetY,
          arrowsOffsetX: arrowsOffsetX,
          arrowsSize: arrowsSize,
          safeY: safeY,
          arrowsColor: arrowsColor,
          child: child,
        ));
  }

  ///盒子按钮参数
  RenderBox boxRenderBox;

  ///盒子尺寸
  Size boxSize;

  ///盒子位置
  Offset boxPositon;

  @override
  Widget build(BuildContext context) {
    if (parentContext == null) {
      return Container();
    }
    boxRenderBox = parentContext?.findRenderObject() as RenderBox;
    boxSize = boxRenderBox?.size;
    boxPositon = boxRenderBox?.localToGlobal(Offset.zero);

    if (boxRenderBox == null || boxSize == null || boxPositon == null) {
      return Container();
    }
    return GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: () {
          RouterUtils.pop(context);
        },
        child: _toDialogWidget());
  }

  ///计算到顶部距离
  double _computerToTopY() {
    //公式: 盒子在屏幕y轴位置 - 顶部状态栏高度 + 盒子自身高度
    double topDistance = boxPositon.dy -
        _screenStatusBarHeight +
        boxSize.height +
        dialogToBoxOffsetY;
    return topDistance;
  }

  ///计算到底部距离
  double _computerToBottomY() {
    //公式: 屏幕高度 - 盒子所在屏幕y轴位置 - 底部状态栏高度
    double bottomDistance = _screenHeight -
        boxPositon.dy -
        _screenBottomBarHeight +
        dialogToBoxOffsetY;
    return bottomDistance;
  }

  ///计算盒子当前位置盒子剩余空间高度
  double _computerExpandHeight() {
    double expandHeight = _screenHeight -
        _screenBottomBarHeight -
        _computerToTopY() -
        safeY -
        _screenStatusBarHeight;
    return expandHeight;
  }

  ///计算箭头的距离
  double _computerToArrowsX() {
    return boxPositon.dx + arrowsOffsetX;
  }

  Widget _toDialogWidget() {
    bool isUpArrows = _computerExpandHeight() >= dialogMaxHeight;

    return Material(
      type: MaterialType.transparency,
      child: Stack(
        children: <Widget>[
          Positioned(
            top: isUpArrows ? _computerToTopY() : null,
            bottom: !isUpArrows ? _computerToBottomY() : null,
            right: 0,
            left: 0,
            child: Container(
              height: dialogMaxHeight,
              child: isUpArrows ? _toUpArrowsWidget() : _toDownArrowsWidget(),
            ),
          )
        ],
      ),
    );
  }

  Widget _toUpArrowsWidget() {
    return Stack(
      fit: StackFit.expand,
      children: <Widget>[
        Positioned(
          top: 0,
          left: _computerToArrowsX(),
          child: customArrowsWidget ??
              Image.asset(
                "images/pop_up_zhixiang.png",
                color: arrowsColor,
                height: arrowsSize.height,
              ),
        ),
        Container(
            margin: EdgeInsets.only(
                top: arrowsSize.height > sAvoidBorderTrimming
                    ? arrowsSize.height - sAvoidBorderTrimming
                    : arrowsSize.height),
            child: _toMainWidget()),
      ],
    );
  }

  Widget _toDownArrowsWidget() {
    return Stack(
      fit: StackFit.expand,
      children: <Widget>[
        Positioned(
          bottom: 0,
          left: _computerToArrowsX(),
          child: customArrowsWidget ??
              Image.asset(
                "images/pop_down_zhixiang.png",
                height: arrowsSize.height,
                color: arrowsColor,
              ),
        ),
        Container(
            margin: EdgeInsets.only(
                bottom: arrowsSize.height > sAvoidBorderTrimming
                    ? arrowsSize.height - sAvoidBorderTrimming
                    : arrowsSize.height),
            child: _toMainWidget()),
      ],
    );
  }

  Widget _toMainWidget() {
    return child ??
        Container(
          margin: const EdgeInsets.symmetric(horizontal: 15),
          decoration: BoxDecoration(
              color: Colors.white, borderRadius: BorderRadius.circular(8)),
        );
  }
}
